package com.jason.ladder.dao.hibernate;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import com.jason.ladder.dao.UserDao;
import com.jason.ladder.entityManager.EMF;
import com.jason.ladder.model.User;

/**
 * This class interacts with Spring's HibernateTemplate to save/delete and
 * retrieve User objects.
 *
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 *   Modified by <a href="mailto:dan@getrolling.com">Dan Kibler</a>
 *   Extended to implement Acegi UserDetailsService interface by David Carter david@carter.net
 *   Modified by <a href="mailto:bwnoll@gmail.com">Bryan Noll</a> to work with 
 *   the new BaseDaoHibernate implementation that uses generics.
*/
@Repository("userDao")
public class UserDaoHibernate implements UserDao {

    /**
     * Constructor that sets the entity to User.class.
     */
    public UserDaoHibernate() {
       
    }
	/**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public List<User> getUsers() {
    	EntityManager em = EMF.get().createEntityManager();
    	List<User> users = new ArrayList<User>();
    	try{
    		users = em.createQuery("select u from User u order by upper(u.username)").getResultList();
  
    	}finally{
    		em.close();
    	}
    	return users;
    }

    @Override
	public User getUser(Integer userId) {
    	EntityManager em = EMF.get().createEntityManager();
		User user;
    	try{
    		user = (User) em.createQuery("select u from User u where id = "+userId).getResultList().get(0);
    		//em.flush();
    	}finally{
    		em.close();
    	}
        return user;
	}
	/**
     * {@inheritDoc}
     */
    public User saveUser(User user) {
    	EntityManager em = EMF.get().createEntityManager();
    	em.setFlushMode(FlushModeType.COMMIT);
    	try{
    		em.getTransaction().begin();
    		em.persist(user);
    		//em.getTransaction().commit();
    		//em.flush();
    		
    	}finally{
    		
    		em.getTransaction().commit();
    		em.close();
    	}
        return user;
    }

    /**
     * Overridden simply to call the saveUser method. This is happenening 
     * because saveUser flushes the session and saveObject of BaseDaoHibernate 
     * does not.
     *
     * @param user the user to save
     * @return the modified user (with a primary key set if they're new)
     */
  
    public User save(User user) {
        return this.saveUser(user);
    }

   

	public List<User> getUsersByRank() {
		EntityManager em = EMF.get().createEntityManager();
		List<User> users = new ArrayList<User>();
    	try{
    		users = em.createQuery("select u from User u order by currentPlace asc").getResultList();
    		users.size();
    		//em.flush();
    	}finally{
    		em.close();
    	}
        return users;

	}
	public Integer getNextRank() {
		EntityManager em = EMF.get().createEntityManager();
		Integer i = 0;
    	try{
    		List<User> users = em.createQuery("select u from User u order by currentPlace desc").getResultList();
    		if(users.size()> 0){
    			User user = (User)em.createQuery("select u from User u order by currentPlace desc").getResultList().get(0);
        		if(null == user.getCurrentPlace() || !(user.getCurrentPlace() > 0)){
        			i=1;
        		}else{
        			i=user.getCurrentPlace()+1;
        		}	
    		}else{
    			i=1;
    		}
    		
    		
    		//em.flush();
    	}finally{
    		em.close();
    	}
       
		return i;
	}
	@Override
	public User getUser(String userId) {
		return this.getUser(Integer.parseInt(userId));
	}
	@Override
	public void remove(User user) {
		EntityManager em = EMF.get().createEntityManager();
    	em.setFlushMode(FlushModeType.COMMIT);
    	try{
    		em.getTransaction().begin();
    		Query query = em.createQuery("delete from User u where u.id = :id");
    		query.setParameter("id", user.getId());
    		query.executeUpdate();
    		//em.getTransaction().commit();
    		//em.flush();
    		
    	}finally{
    		
    		em.getTransaction().commit();
    		em.close();
    	}
		
	}
    
}
